﻿using Common.Exceptions;
using Common.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Wallpaper.Data.Context;
using Wallpaper.Data.IDal;
using Wallpaper.Models.DTOs.Requests.Role;
using Wallpaper.Models.DTOs.Responses.Role;
using Wallpaper.Models.Entities;
using Wallpaper.Models.Options;
using Wallpaper.Services.IService;

namespace Wallpaper.Services.Service
{
    public class RoleService : IRoleService
    {
        readonly ILogger<RoleService> _logger;
        readonly IRoleDal _roleDal;
        readonly WallpaperDbContext _dbContext;
        readonly IAdminDal _adminDal;
        

        public RoleService(ILogger<RoleService> logger, IRoleDal roleDal, WallpaperDbContext dbContext, IAdminDal adminDal)
        {
            _logger = logger;
            _roleDal = roleDal;
            _dbContext = dbContext;
            _adminDal = adminDal;
           
        }

        /// <summary>
        /// 角色绑定菜单
        /// </summary>
        /// <param name="roleId"></param>
        /// <param name="menuIds"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<bool> BindMenuAsync(string id, List<string> menuIds)
        {
            if (string.IsNullOrWhiteSpace(id))
            {
                throw new ArgumentNullException(nameof(menuIds), "角色Id不能为空");
            }
            if (menuIds == null)
            {
                throw new ArgumentNullException("菜单Id不能为空", nameof(menuIds));
            }


            using var transaction = await _dbContext.Database.BeginTransactionAsync();
            try
            {
                // 批量删除
                await _adminDal.GetDbSet<RoleMenu>()
                    .Where(rm => rm.RoleId == id)
                    .ExecuteDeleteAsync();

                // 批量添加
                if (menuIds.Any())
                {
                    var newRoleMenus = menuIds.Select(menuId => new RoleMenu
                    {
                        RoleId = id,
                        MenuId = menuId,
                    }).ToList();

                    await _adminDal.GetDbSet<RoleMenu>().AddRangeAsync(newRoleMenus);
                    await _dbContext.SaveChangesAsync();
                }

                await transaction.CommitAsync();
                return true;
            }
            catch
            {
                await transaction.RollbackAsync();
                throw;
            }

        }

        /// <summary>
        /// 角色绑定权限
        /// </summary>
        /// <param name="id"></param>
        /// <param name="permissions"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<bool> BindPermissionAsync(string id, List<string> permissionIds)
        {
            if (string.IsNullOrWhiteSpace(id))
            {
                throw new ArgumentException("角色Id不能为空", nameof(id));
            }
            if (permissionIds == null)
            {
                throw new ArgumentNullException(nameof(permissionIds), "权限列表不能为空");
            }

            using var transaction = await _dbContext.Database.BeginTransactionAsync();
            try
            {
                // ✅ 使用 _dbContext 的 DbSet
                await _dbContext.Set<RolePermission>()
                    .Where(rm => rm.RoleId == id)
                    .ExecuteDeleteAsync();

                // 批量添加
                if (permissionIds.Any())
                {
                    var newRolePermissions = permissionIds.Select(permissionId => new RolePermission
                    {
                        RoleId = id,
                        PermissionId = permissionId,
                        Role = null,        // ✅ 切断导航属性跟踪
                        Permission = null   // ✅ 切断导航属性跟踪

                    }).ToList();

                    await _dbContext.Set<RolePermission>().AddRangeAsync(newRolePermissions);
                    await _dbContext.SaveChangesAsync(); // ✅ 使用 _dbContext 保存
                }

                await transaction.CommitAsync();
                return true;
            }
            catch
            {
                await transaction.RollbackAsync();
                throw;
            }
        }


        /// <summary>
        /// 角色绑定账号
        /// </summary>
        /// <param name="roleId"></param>
        /// <param name="adminIds"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<bool> BindRoleAsync(string roleId, IEnumerable<string> adminIds)
        {
            if (string.IsNullOrEmpty(roleId))
            {
                //参数验证用ArgumentException
                throw new ArgumentException("角色Id不能为空", nameof(roleId));
            }

            // 开始事务
            await using var transaction = await _dbContext.Database.BeginTransactionAsync();

            try
            {
                // 获取当前角色下所有的管理员
                List<Admin> list = await _roleDal.GetDbSet<Admin>()
                    .Where(a => a.RoleId == roleId && !a.IsSuperAdmin)
                    .ToListAsync();

                if (adminIds == null || !adminIds.Any())
                {
                    foreach (var admin in list)
                    {
                        admin.RoleId = null;
                        await _adminDal.UpdateEntityAsync(admin); // 立即提交，但在事务中
                    }
                }
                else
                {
                    // 先清空当前角色下的所有管理员
                    foreach (var admin in list)
                    {
                        admin.RoleId = null;
                        await _adminDal.UpdateEntityAsync(admin);
                    }

                    // 为指定的管理员设置角色
                    foreach (var adminId in adminIds)
                    {
                        var admin = await _roleDal.GetDbSet<Admin>()
                            .FirstOrDefaultAsync(i => i.Id == adminId && !i.IsSuperAdmin);
                        if (admin != null)
                        {
                            admin.RoleId = roleId;
                            await _adminDal.UpdateEntityAsync(admin);
                        }
                    }
                }

                // 提交事务
                await transaction.CommitAsync();
                return true;
            }
            catch
            {
                await transaction.RollbackAsync();
                throw;
            }
        }



        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="BusinessException"></exception>
        public async Task<bool> CreateAsync(CreateRoleRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            if (string.IsNullOrWhiteSpace(request.RoleName))
            {
                throw new ArgumentException("角色名称不能为空", nameof(request.RoleName));
            }

            if (string.IsNullOrWhiteSpace(request.RoleCode))
            {
                throw new ArgumentException("角色编码不能为空", nameof(request.RoleCode));
            }

            // 2. 业务规则验证 - 角色名是否重复
            var existsByName = await _roleDal.GetQueryable()
                .AnyAsync(r => r.RoleName == request.RoleName && !r.IsDeleted);
            if (existsByName)
            {
                throw new BusinessException($"角色名称 '{request.RoleName}' 已存在", 400);
            }
            // 3. 业务规则验证 - 角色编码是否重复
            var existsByCode = await _roleDal.GetQueryable()
                .AnyAsync(r => r.RoleCode == request.RoleCode && !r.IsDeleted);
            if (existsByCode)
            {
                throw new BusinessException($"角色编码 '{request.RoleCode}' 已存在", 400);
            }

            // 4. 创建角色实体
            var role = new Role
            {
                Id = Guid.NewGuid().ToString(),
                RoleName = request.RoleName,
                RoleCode = request.RoleCode,
                Description = request.Description,
                IsEnabled = request.IsEnabled,
            };
            return await _roleDal.CreateEntityAsync(role);

        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<bool> DeleteAsync(string id)
        {
            // 1. 参数验证
            if (string.IsNullOrWhiteSpace(id))
                throw new ArgumentNullException("角色ID不能为空", nameof(id));

            // 2. 检查角色是否存在
            var existingRole = await _roleDal.GetByIdAsync(id);

            if (existingRole == null || existingRole.IsDeleted)
                throw new BusinessException("角色不存在或已被删除", 404);

            // 3. 防止删除系统内置角色
            if (existingRole.RoleCode == "super_admin")
                throw new BusinessException("系统内置角色不允许删除", 400);

            // 4. 检查是否有管理员在使用该角色（仍然需要检查！）
            var hasAdmins = await _dbContext.Admins
                .AnyAsync(a => a.RoleId == id );

            if (hasAdmins)
                throw new BusinessException("该角色下还有管理员，无法删除", 400);

            // 6. 执行删除
            return  await _roleDal.DeleteEntityAsync(existingRole);
        }


        /// <summary>
        /// 获取已绑定角色的账号
        /// </summary>
        /// <param name="roleId"></param>
        /// <returns></returns>
        public async Task<List<OptionsResponse>> GetBindInfoAsync(string roleId)
        {
            if (string.IsNullOrEmpty(roleId))
            {
                throw new ArgumentNullException("角色Id不能为空", nameof(roleId));
            }
            List<OptionsResponse> list = await _roleDal.GetDbSet<Admin>().Where(a => a.RoleId == roleId && !a.IsSuperAdmin &&
                   a.IsEnabled &&           // 只查询启用的账号
                   !a.IsDeleted)
            .OrderBy(u => u.Account)
            .Select(u => new OptionsResponse
            {
                Value = u.Id,
                Label = u.Account
            }).ToListAsync();
       
            return list;
        }

    
        /// <summary>
        /// 获取角色已绑定的菜单
        /// </summary>
        /// <param name="roleId"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<List<OptionsResponse>> GetRoleBindMenuAsync(string roleId)
        {
            var list = await (from rm in _roleDal.GetDbSet<RoleMenu>()
                              join m in _roleDal.GetDbSet<Menu>() on rm.MenuId equals m.Id
                              where rm.RoleId == roleId && m.IsEnabled
                              orderby m.Sort
                              select new OptionsResponse
                              {
                                  Value = m.Id,
                                  Label = m.Name
                              })
                              .ToListAsync();

            return list;
        }




        /// <summary>
        /// 获取角色信息
        /// </summary>
        /// <returns></returns>
        public async Task<List<RoleOptionResponse>> GetRoleOptionsAsync()
        {
            List<RoleOptionResponse> list = await _roleDal.GetDbSet<Role>()
            .Select(r => new RoleOptionResponse  
            {
                RoleId = r.Id,
                RoleName = r.RoleName
            })
            .ToListAsync();
            return list;
        }

        /// <summary>
        /// 获取角色已绑定的权限
        /// </summary>
        /// <param name="roleId"></param>
        /// <returns></returns>
        public async Task<List<string>> GetRolePermissionsAsync(string roleId)
        {
            if (roleId == null)
            {
                throw new ArgumentNullException("角色ID不能为空", nameof(roleId));
            }
            var role=await  _roleDal.GetByIdAsync(roleId);
            if (role == null)
            {
                throw new BusinessException("角色不存在或已被删除", 404);
            }
            var permissionIds = await _dbContext.RolePermissions
               .AsNoTracking() //只读查询
               .Where(rp => rp.RoleId == roleId)
               .Select(rp => rp.PermissionId)
               .ToListAsync();

            return permissionIds;



        }




        /// <summary>
        /// 分页
        /// </summary>
        /// <param name="queryRequest"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<PagedResult<RolePageResponse>> PageAsync(RoleQueryRequest queryRequest)
        {
            var query = _roleDal.GetQueryable();

            // 调试1：查看基础查询的SQL
            Console.WriteLine("=== 基础查询SQL ===");
            var baseSql = query.ToQueryString();
            Console.WriteLine(baseSql);

            // 关键词搜索（搜索角色名称或角色编码）
            if (!string.IsNullOrWhiteSpace(queryRequest.Keyword))
            {
                query = query.Where(r => r.RoleName.Contains(queryRequest.Keyword)
                                      || r.RoleCode.Contains(queryRequest.Keyword));
            }

            // 角色名称筛选
            if (!string.IsNullOrWhiteSpace(queryRequest.RoleName))
            {
                query = query.Where(r => r.RoleName.Contains(queryRequest.RoleName));
            }

            // 角色编码筛选
            if (!string.IsNullOrWhiteSpace(queryRequest.RoleCode))
            {
                query = query.Where(r => r.RoleCode.Contains(queryRequest.RoleCode));
            }

            // 启用状态筛选
            if (queryRequest.IsEnabled.HasValue)
            {
                query = query.Where(r => r.IsEnabled == queryRequest.IsEnabled.Value);
            }

            // 创建时间范围筛选（从 TimeRangeQuery 继承）
            if (queryRequest.StartTime.HasValue)
            {
                query = query.Where(r => r.CreatedAt >= queryRequest.StartTime.Value);
            }

            if (queryRequest.EndTime.HasValue)
            {
                query = query.Where(r => r.CreatedAt <= queryRequest.EndTime.Value);
            }

            // 排序（按创建时间降序）
            query = query.OrderByDescending(r => r.CreatedAt);

            // 获取总数
            var totalCount = await query.CountAsync();

            // 分页
            var items = await query
                .Skip((queryRequest.Page - 1) * queryRequest.PageSize)
                .Take(queryRequest.PageSize)
                .Select(r => new RolePageResponse
                {
                    Id = r.Id,
                    roleName = r.RoleName,
                    roleCode = r.RoleCode,
                    Description = r.Description,
                    CreatedTime = r.CreatedAt,
                    UpdatedTime = r.UpdatedAt,
                    IsEnabled = r.IsEnabled
                })
                .ToListAsync();

            return new PagedResult<RolePageResponse>
            {
                Page = queryRequest.Page,
                PageSize = queryRequest.PageSize,
                TotalCount = totalCount,
                Items = items
            };
        }

        /// <summary>
        /// 更新角色
        /// </summary>
        /// <param name="id"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentException"></exception>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="BusinessException"></exception>
        public async Task<bool> UpdateAsync(string id, CreateRoleRequest request)
        {
            // 1. 参数基础验证
            if (string.IsNullOrWhiteSpace(id))
            {
                throw new ArgumentNullException("角色ID不能为空", nameof(id));
            }

            if (request == null)
            {
                throw new ArgumentNullException("更新数据不能为空", nameof(request));
            }

            // 2. 检查角色是否存在
            var existingRole = await _roleDal.GetByIdAsync(id);
            if (existingRole == null || existingRole.IsDeleted)
                throw new BusinessException("角色不存在或已被删除", 404);

            // 3. 业务规则验证 - 角色名是否重复（排除自己）
            var existsByName = await _roleDal.GetQueryable()
                .AnyAsync(r => r.RoleName == request.RoleName && r.Id != id && !r.IsDeleted);
            if (existsByName)
                throw new BusinessException($"角色名称 '{request.RoleName}' 已存在", 400);

            // 4. 业务规则验证 - 角色编码是否重复（排除自己）
            var existsByCode = await _roleDal.GetQueryable()
                .AnyAsync(r => r.RoleCode == request.RoleCode && r.Id != id && !r.IsDeleted);
            if (existsByCode)
                throw new BusinessException($"角色编码 '{request.RoleCode}' 已存在", 400);

            // 5. 防止修改系统内置角色（如果有的话）
            if (existingRole.RoleCode == "super_admin")
                throw new BusinessException("系统内置角色不允许修改", 400);

            // 6. 更新角色信息
            existingRole.RoleName = request.RoleName;
            existingRole.RoleCode = request.RoleCode;
            existingRole.Description = request.Description;
            existingRole.IsEnabled = request.IsEnabled;

            // 7. 保存到数据库
            return  await _roleDal.UpdateEntityAsync(existingRole);

         

        }
    }
}
